/// 获取客户端IP
/// @return {String} IP
function getIp() {
	var proxy = $("HTTP_X_FORWARDED_FOR", "serv"),
		ip = proxy && proxy.indexOf("unknown") != -1 ? proxy.split(/,;/g)[0] : $("REMOTE_ADDR", "serv");
		
	ip = ip.trim().substring(0, 15);
	return "::1" === ip ? "127.0.0.1" : ip;
};


	/**
	 * Raw POST的解析器。Raw Post也是标准HTTP POST方式的一种，但不像key1=value2&key2=value2的形式提交数据，
	 * 而是一堆二进制的数据。
	 * 浏览器提交的POST数据视作原始的实际，须经过Adodb.Stream二进制解码后才可以使用。
	 * 注意：一旦使用过该方法。Request.Form('key')就无法使用，但QueryString仍可用。
	 * @return {Object}
	 */
    function rawPost(){
    	with(new ActiveXObject('Adodb.Stream')){
			try{
				Open();
				Type = 2;// 2 = adTypeText
				WriteText(Request.BinaryRead(Request.TotalBytes));
				Position = 0;
				Charset  = "us-ascii";// gb2312？
				Position = 2;
				// 使用 eval()函数时，必须要一个变量来承载！
				eval('this.requestObj = ' + ReadText());
				return this.requestObj;
			}catch(e){
				throw e;
			}finally{
				Close();
			}
		}
    }
    


// Request
;(function(){
	var  
		 getQuery
		,getForm
//    	// 不进行字符串转换的方法
    	,binaryRead;
	
	if($$.Server.isNodeJS){
		log	= console.log;
	}else if($$.Server.isASP){
		var every = function(emu, isAutoType){
			var 
				 key
				,e
				,v
				,queryObj = {}
				,i = 0;
				
			if(!emu && emu.count <= 0)return queryObj;
				
	        for(e = new Enumerator(emu); !e.atEnd(); e.moveNext()){
	            key = e.item().toString();
	            v   = emu(key)(); // MS ASP这里好奇怪，不加()不能返回字符串
	            
//	        	v 	= decodeURI(v);
//	            v 	= unescape(v);
	            
	            queryObj[key] = isAutoType ? $$.getPerm(v) : v;
	            i++;
	        }
	        
	        queryObj._count = i; // 字段总数
	        return queryObj;
		};
		
		/**
		 * 获取来自表单的各个字段的数据。HTTP FORM所提交的数据乃是key/value配对的结构。
		 * 本函数是把这些key/value集合转化成为JavaScript对象。这是post包最核心的函数。
		 * 对各个字段有decodeURI()、unescape()、$$.getPerm()自动类型转化的功能。
		 * @param {Boolean/String} isAllRequest true表示为返回QueryString和Form的Request对象集合。
		 * 如果指定form则返回表单的hash值，如果指定QueryString则返回URL上面的参数hash。
		 * @param {Boolean} isAutoType 是否进行自动类型转换。
		 * @return {Object} 客户端提交的数据或查询参数。
		 */
		getQuery = function(isAllRequest, isAutoType){
			if(typeof isAllRequest == 'string') isAllRequest = isAllRequest.toLowerCase();
			switch(isAllRequest){
				case true:
					var 
						 _queryObj 	= every(Request.QueryString, isAutoType)
						,_formObj 	= every(Request.Form, isAutoType)
						,_count		= _queryObj._count + _formObj._count
						,_allObj;

					for(var i in _formObj){
						_queryObj[i] =_formObj[i];// 如果越到相同的key，则保留form的。
					}
					_allObj = _queryObj;
					_allObj._count = _count;
					
					return _allObj;
				break;
				case 'form':
					return every(Request.Form, isAutoType);
				break;
				case 'querystring':
				default:
					return every(Request.QueryString, isAutoType);
			}
		}
	}
	
	/**
	 * @class $$.Request
	 */
	$$.Request = function (){
		
	}
	$$.Request.prototype = {
		/**
		 * 是否POST提交数据。
		 * @return {Boolean}
		 */
		 isPOST			: function(){
			return Request.ServerVariables('HTTP_METHOD')() == "POST";
		 }
		 
		/**
		 * 返回是否Raw 的POST。这个方法在某种场合必须使用，例如Ext.Direct。
		 * 约定：凡application/json的提交均视作Raw POST。
		 * @return {Boolean}
		 */
		,isRawPOST		: function(){
    		return this.isPOST() && (Request.ServerVariables('Content_Type')().indexOf('application/json')) != -1
		}
		,getQuery: getQuery
		,getForm : getForm
		
		/**
		 * 返回页面的路径。
		 * @return {String} url
		 */
		,getPath : function(){
			return Request.ServerVariables('URL')();
		}
		,hash	 : function(key){
			return this.getQuery(true)[key];
		}
		
		,method	 : function(){
			return Request.ServerVariables('HTTP_METHOD')();
		}
		
		/**
		 * Raw POST的解析器。Raw Post也是标准HTTP POST方式的一种，但不像key1=value2&key2=value2的形式提交数据，
		 * 而是一堆二进制的数据。
		 * 浏览器提交的POST数据视作原始的实际，须经过Adodb.Stream二进制解码后才可以使用。
		 * 注意：一旦使用过该方法。Request.Form('key')就无法使用，但QueryString仍可用。
		 * @return {Object}
		 */
	    ,getRawPost: function (){
	    	with(new ActiveXObject('Adodb.Stream')){
				open();
				type = 2;// 2 = adTypeText
				writeText(Request.binaryRead(Request.totalBytes));
				position = 0;
				charset  = "us-ascii";// gb2312？
				position = 2;
				// 使用 eval()函数时，必须要一个变量来承载！
				eval('this.requestObj = ' + readText());
				close();
				return this.requestObj;
			}
	    }  
	};
})();
